﻿using System;
using System.Linq;
using Dapper;
using NLog;
using Oracle.ManagedDataAccess.Client;
using Quartz;
using Quartz.Impl.Matchers;
using Raise.Workbench.Service.Models;
using Raise.Workbench.Tools;

namespace Raise.Workbench.Service {
    /// <summary>
    /// 创建调度作业 参考文献：https://blog.csdn.net/changtianshuiyue/article/details/51533726
    /// </summary>
    public class CreateJobs {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger(typeof(CreateJobs));

        public void Create(IScheduler scheduler) {
            if(scheduler == null) {
                Logger.Error(new ArgumentException("scheduler不能为空"));
                return;
            }
            using(var connection = new OracleConnection(Utils.GetConnectString())) {
                var sql = @"Select id,
                               cron,
                               description,
                               triggername,
                               jobname,
                               method,
                               postbody,
                               servicename,
                               author,
                               contenttype,
                               isauthentication,
                               username,
                               password,
                               groupname,
                               uniqueCode,
                               isWebService,
                               address from RuleConfig where status = :status and runStatus = :runStatus";
                var configs = connection.Query<RuleConfig>(sql, new { status = (int)BasicStatus.有效, runStatus = (int)RunStatus.启用 }).ToList();
                Logger.Info($"目前可用可用调度数量为{configs.Count}");
                foreach(var ruleConfig in configs) {
                    IJobDetail job = JobBuilder
                    .Create<ExecuteJob>()
                    .WithIdentity(ruleConfig.JobName, ruleConfig.GroupName)
                    .RequestRecovery()
                    .WithDescription(ruleConfig.Description)
                    .Build();
                    //构造一个接下来10秒内执行的触发器
                    ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity(ruleConfig.TriggerName, ruleConfig.GroupName ?? Guid.NewGuid().ToString()).WithCronSchedule(ruleConfig.Cron)
                        .StartAt(DateBuilder.FutureDate(10, IntervalUnit.Second))
                        .WithDescription(ruleConfig.Description)
                        .Build();
                    //将唯一标识传入执行方法内部，内部根据标识，处理相关的逻辑
                    job.JobDataMap.Put(GlobalVar.UNIQUE_CODE, ruleConfig.UniqueCode);
                    JobListener listener = new JobListener();
                    IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(job.Key);
                    scheduler.ListenerManager.AddJobListener(listener, matcher);
                    scheduler.ScheduleJob(job, trigger);
                }
            }
        }
    }
}
